const jwt = require('jsonwebtoken');
const UserPrisma = require('../models/UserPrisma');
const Administrator = require('../models/AdministratorPrisma');

/**
 * JWT认证中间件
 * 验证请求头中的token，并将用户信息添加到req.user中
 */
const authenticateToken = async (req, res, next) => {
  try {
    // 从请求头获取token
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      return res.status(401).json({
        success: false,
        message: '访问令牌缺失'
      });
    }

    // 验证token
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    
    // 查询用户信息
    const user = await UserPrisma.findById(decoded.user_id);
    if (!user) {
      return res.status(401).json({
        success: false,
        message: '用户不存在'
      });
    }

    // 将用户信息添加到请求对象中
    req.user = user;
    next();
  } catch (error) {
    console.error('Token验证失败:', error.message);
    
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({
        success: false,
        message: '无效的访问令牌'
      });
    }
    
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({
        success: false,
        message: '访问令牌已过期'
      });
    }
    
    return res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 可选的JWT认证中间件
 * 如果有token则验证，没有token则继续执行
 */
const optionalAuth = async (req, res, next) => {
  try {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (token) {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      const user = await UserPrisma.findById(decoded.user_id);
      if (user) {
        req.user = user;
      }
    }
    
    next();
  } catch (error) {
    // 可选认证失败时不返回错误，继续执行
    next();
  }
};

/**
 * 检查用户是否已激活
 */
const requireActive = (req, res, next) => {
  if (!req.user) {
    return res.status(401).json({
      success: false,
      message: '请先登录'
    });
  }

  if (req.user.status !== 'active') {
    return res.status(403).json({
      success: false,
      message: '账户未激活，请先激活账户'
    });
  }

  next();
};

/**
 * 检查用户发布额度
 */
const requireCredits = (req, res, next) => {
  if (!req.user) {
    return res.status(401).json({
      success: false,
      message: '请先登录'
    });
  }

  if (req.user.publishing_credits <= 0) {
    return res.status(403).json({
      success: false,
      message: '发布额度不足，请购买套餐'
    });
  }

  next();
};

/**
 * 生成JWT token
 * @param {Object} payload 载荷数据
 * @param {string} expiresIn 过期时间
 * @returns {string} JWT token
 */
const generateToken = (payload, expiresIn = process.env.JWT_EXPIRES_IN || '7d') => {
  return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn });
};

/**
 * 验证JWT token
 * @param {string} token JWT token
 * @returns {Object} 解码后的载荷
 */
const verifyToken = (token) => {
  return jwt.verify(token, process.env.JWT_SECRET);
};

/**
 * 管理员JWT认证中间件
 * 验证请求头中的token，并将管理员信息添加到req.admin中
 */
const authenticateAdmin = async (req, res, next) => {
  try {
    // 从请求头获取token
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      return res.status(401).json({
        success: false,
        message: '访问令牌缺失'
      });
    }

    // 验证token
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    // 检查是否为管理员token
    if (!decoded.admin_id) {
      return res.status(401).json({
        success: false,
        message: '无效的管理员令牌'
      });
    }

    // 查找管理员
    const admin = await Administrator.findById(decoded.admin_id);
    if (!admin) {
      return res.status(401).json({
        success: false,
        message: '管理员不存在'
      });
    }

    // 将管理员信息添加到请求对象中
    req.admin = {
      id: admin.id,
      username: admin.username
    };

    next();
  } catch (error) {
    console.error('管理员Token验证失败:', error.message);
    return res.status(401).json({
      success: false,
      message: '无效的访问令牌'
    });
  }
};

/**
 * 生成管理员JWT token
 * @param {Object} admin 管理员信息
 * @returns {string} JWT token
 */
const generateAdminToken = (admin) => {
  const payload = {
    admin_id: admin.id,
    username: admin.username
  };

  return jwt.sign(payload, process.env.JWT_SECRET, {
    expiresIn: process.env.JWT_EXPIRES_IN || '7d'
  });
};

module.exports = {
  authenticateToken,
  optionalAuth,
  requireActive,
  requireCredits,
  generateToken,
  verifyToken,
  authenticateAdmin,
  generateAdminToken
};
